using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class SDFRenderFeature : ScriptableRendererFeature
{
    [Serializable]
    public struct ShapeData
    {
        public Vector3 position;
        public Vector3 size;
        public Vector4 color;
        public Vector4 custom;
        public int shapeType;
        public int operation;
        public float blendStrength;
        public int numChildren;

        static public int GetSize()
        {
            return sizeof(float) * 15 + sizeof(int) * 3;
        }
    }

    [Serializable]
    public class SDFShapeSetting
    {
        public RenderPassEvent passEvent ;
        [Range(0f, 1f)]
        public float degreeOfFusion = 1;
        public float resolutionDivisor = 4;
        [Range(0.1f, 50f)]
        public float distabilizationAmplitude = 10;
        [Range(0f, 10f)]
        public float distabilizationSpeed = 0;
        [Range(0f, 20f)]
        public float distabilizationFraquence = 3;
    }

    public SDFShapeSetting m_Setting = new SDFShapeSetting();
    SDFRenderPass m_ScriptablePass;

    public Material m_Material;
    /// <inheritdoc/>
    public override void Create()
    {
        m_ScriptablePass = new SDFRenderPass(m_Material, m_Setting);
        // Configures where the render pass should be injected.
    }

    // Here you can inject one or multiple render passes in the renderer.
    // This method is called when setting up the renderer once per-camera.
    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        renderer.EnqueuePass(m_ScriptablePass);
    }
}

public class ShapeDataProvider 
{
    // 双缓冲系统
    private SDFRenderFeature.ShapeData[] m_FrontBuffer;
    private SDFRenderFeature.ShapeData[] m_BackBuffer;
    private readonly object m_BufferLock = new object();
    
    // 主线程更新数据
    public void UpdateShapeData(SDFRenderFeature.ShapeData[] newData)
    {
        lock (m_BufferLock)
        {
            // 只在需要时重新分配内存
            if (m_BackBuffer == null || m_BackBuffer.Length != newData.Length)
            {
                m_BackBuffer = new SDFRenderFeature.ShapeData[newData.Length];
            }
            
            // 复制数据到后台缓冲区
            Array.Copy(newData, m_BackBuffer, newData.Length);
        }
    }
    
    // 渲染线程安全获取数据
    public SDFRenderFeature.ShapeData[] GetShapeDataForRender()
    {
        lock (m_BufferLock)
        {
            // 交换缓冲区
            var temp = m_FrontBuffer;
            m_FrontBuffer = m_BackBuffer;
            m_BackBuffer = temp;
            
            return m_FrontBuffer;
        }
    }
}
